import { Quaternion, Vector3 } from "three";
import { CreateMeta, HoleMeta } from "../meta/MetaClass";
import AModelFmulaUtils from "../utils/AModelFmulaUtils";
import AluGeoUtil from "./utils/AluGeoUtil";
import VectorUtils from "../utils/VectorUtils";


/** 圆弧倒角平板 网格*/
export default class RChamferPGMY {

    /** 圆弧的x轴点*/
    private _r_x = 50;
    /** 圆弧的y轴点*/
    private _r_y = 50;
    /** 底厚*/
    private _b_t = 6;

    private _vertices: Array<number>;
    get vertices() { return this._vertices; }

    private _indices: Array<number>;
    get indices() { return this._indices; }


    /** 底板的宽度 固定15 文杰指定*/
    private _bw: number = 15;

    constructor(data: AIBasicParams) {
        this._vertices = [];
        this._indices = [];

        this.generate(data);
        this.setDuan(data);
    }

    private setDuan(data: AIBasicParams) {
        data["duan"] = [
            0, 0, 0,
            data.L, 0, 0,
        ];
        data["zhong"] = {
            L: [
                {
                    pointer: [data.L, 0, +data.BKH / 2],
                    center: [data.L / 2, 0, +data.BKH / 2]
                },
            ],
            RL: [
                {
                    pointer: [0, 0, +data.BKH / 2],
                    center: [data.L / 2, 0, +data.BKH / 2]
                },
            ]
        }
    }

    private generate(data: AIBasicParams) {

        //顶板
        this._top(data);

        //光面板
        this._plank(data);

        //两侧板
        this._plank_l(data);
        this._plank_r(data);

        //底板
        this._bottom(data);

        //圆弧板
        this._rad(data);


        //易拆
        this._gap(data);

        //横肋
        this._rib(data);

        for (let i: number = 0; i < this._vertices.length; i += 3) {

            this._vertices[i + 1] -= +data.W

        }

    }

    /** 顶板*/
    private _top(data: AIBasicParams) {

        let l = +data.BKH, w = +data.L, t = +data.bkT;
        let offsetY = +data.W;

        let back = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0,
        ];

        let front = [
            0, 0, t, w, 0, t, w, l, t, 0, l, t,
        ];

        //     AK.p_skkw,
        // AK.p_xkkw,
        // AK.p_zkkw,
        // data.p_zkkw = data["o_p_zkkw"];


        let holes = AModelFmulaUtils.getHolesbyExpress(data.p_zkkw, w);
        let filterHole = AluGeoUtil.filterHole(w - (+data.BKDia * 0.5), holes);
        holes = AModelFmulaUtils.getHolesbyExpress(data.p_zkkw, w, 2, data, "p_zkkw", Math.abs(filterHole.length - holes.length));


        let h = new HoleMeta(+data.BKDia * 0.5, l - +data.BKKJMDis, holes, "x");
        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        let q = new Quaternion();
        q.setFromAxisAngle(new Vector3(1, 0, 0), Math.PI * 0.5);
        for (let i: number = 0; i < r.vertices.length; i += 3) {
            VectorUtils.assistVector3.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]);
            VectorUtils.assistVector3.applyQuaternion(q);

            r.vertices[i] = VectorUtils.assistVector3.x;
            r.vertices[i + 1] = VectorUtils.assistVector3.y + offsetY;
            r.vertices[i + 2] = VectorUtils.assistVector3.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }


    /** 光面板*/
    private _plank(data: AIBasicParams) {
        // DJXQW

        let l = +data.W - 50, w = +data.L, t = +data.GMT;
        let offsetY = 50;

        let back = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0,
        ];

        let front = [
            0, 0, t, w, 0, t, w, l, t, 0, l, t,
        ];


        // let h = new HoleMeta(data.BKDia * 0.5, w - bj, hole);
        let c = new CreateMeta(t, front, back, null);
        let r = AluGeoUtil.createBoardWithHole(c);

        // let q = new Quaternion();
        // q.setFromAxisAngle(new Vector3(1, 0, 0), Math.PI * 0.5);
        for (let i: number = 0; i < r.vertices.length; i += 3) {
            VectorUtils.assistVector3.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]);
            // VectorUtils.assistVector3.applyQuaternion(q);

            // r.vertices[i] = VectorUtils.assistVector3.x;
            r.vertices[i + 1] = VectorUtils.assistVector3.y + offsetY;
            // r.vertices[i + 2] = VectorUtils.assistVector3.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }


    /** 左侧板 */
    private _plank_l(data: AIBasicParams) {
        let l = +data.W, sl = 50, sw = 50, w = +data.BKH, t = +data.bkT;

        let back = [
            sw, 0, -t, w, 0, -t, w, l, -t, 0, l, -t, 0, sl, -t
        ];

        let front = [
            sw, 0, 0, w, 0, 0, w, l, 0, 0, l, 0, 0, sl, 0
        ];

        // data.p_xkkw = data["o_p_xkkw"];

        // let holes = AModelFmulaUtils.getHolesbyExpress(data.p_xkkw, l);
        // let filterHole = AluGeoUtil.filterHole(l - sl - (+data.BKDia * 0.5), holes);
        let holes = AModelFmulaUtils.getHolesbyExpress(data.p_xkkw, l, 2, data, "p_xkkw");

        let h = new HoleMeta(data.BKDia * 0.5, w - (+data.BKKJMDis), AluGeoUtil.reverseHole(l, holes));
        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        let q = new Quaternion();
        q.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI * -0.5);
        for (let i: number = 0; i < r.vertices.length; i += 3) {
            VectorUtils.assistVector3.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]);
            VectorUtils.assistVector3.applyQuaternion(q);

            r.vertices[i] = VectorUtils.assistVector3.x;
            r.vertices[i + 1] = VectorUtils.assistVector3.y;
            r.vertices[i + 2] = VectorUtils.assistVector3.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }


    /** 右侧板 */
    private _plank_r(data: AIBasicParams) {
        let l = +data.W, sl = 50, sw = 50, w = +data.BKH, t = +data.bkT;
        let offsetX = +data.L;

        let back = [
            sw, 0, 0, w, 0, 0, w, l, 0, 0, l, 0, 0, sl, 0
        ];

        let front = [
            sw, 0, t, w, 0, t, w, l, t, 0, l, t, 0, sl, t
        ];

        // data.p_skkw = data["o_p_skkw"];

        // let holes = AModelFmulaUtils.getHolesbyExpress(data.p_skkw, l);
        // let filterHole = AluGeoUtil.filterHole(l - sl - (+data.BKDia * 0.5), holes);
        let holes = AModelFmulaUtils.getHolesbyExpress(data.p_skkw, l, 2, data, "p_skkw");

        let h = new HoleMeta(data.BKDia * 0.5, w - (+data.BKKJMDis), AluGeoUtil.reverseHole(l, holes));

        // let h = new HoleMeta(data.BKDia * 0.5, w - bj, hole);
        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        let q = new Quaternion();
        q.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI * -0.5);
        for (let i: number = 0; i < r.vertices.length; i += 3) {
            VectorUtils.assistVector3.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]);
            VectorUtils.assistVector3.applyQuaternion(q);

            r.vertices[i] = VectorUtils.assistVector3.x + offsetX;
            r.vertices[i + 1] = VectorUtils.assistVector3.y;
            r.vertices[i + 2] = VectorUtils.assistVector3.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }


    /** 底板*/
    private _bottom(data: AIBasicParams) {
        let l = +data.BKH - this._r_x, w = +data.L, t = this._b_t;
        let offsetZ = this._r_x;

        let back = [
            0, 0, 0, w, 0, 0, w, l, 0, 0, l, 0,
        ];

        let front = [
            0, 0, t, w, 0, t, w, l, t, 0, l, t,
        ];


        // let h = new HoleMeta(data.BKDia * 0.5, w - bj, hole);
        let c = new CreateMeta(t, front, back, null);
        let r = AluGeoUtil.createBoardWithHole(c);

        let q = new Quaternion();
        q.setFromAxisAngle(new Vector3(1, 0, 0), Math.PI * 0.5);
        for (let i: number = 0; i < r.vertices.length; i += 3) {
            VectorUtils.assistVector3.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]);
            VectorUtils.assistVector3.applyQuaternion(q);

            r.vertices[i] = VectorUtils.assistVector3.x;
            r.vertices[i + 1] = VectorUtils.assistVector3.y + t;
            r.vertices[i + 2] = VectorUtils.assistVector3.z + offsetZ;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }


    /** 弧板*/
    private _rad(data: AIBasicParams) {

        let sl = this._r_y, sw = this._r_x, t = +data.GMT, l = +data.L, rd = +data.arcR;

        let r = this.createSellipse(sl, sw, t, l, rd);

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);

    }



    /** 一个弧体
     * x x上的点
     * y y上的点
     * t 两个弧之间的厚度
     * l 弧宽
     * r 弧半径
    */
    private createSellipse(x: number, y: number, t: number = 100, l: number = 600, r: number = 100): GeometryReturnMeta<Array<any>> {
        let vec = [];
        let indics = [];

        let c = AluGeoUtil.toCircleCenter(x, y, r, t);
        let a = AluGeoUtil.circlePath(c.center.x, c.center.y, r, c.o_arc_deg, c.o_arc_r_deg, 128);
        let b = AluGeoUtil.circlePath(c.center.x, c.center.y, c.inner_arc_radius, c.i_arc_deg, c.i_arc_r_deg, 128);

        //外弧面
        let aa = this.ellipse(a, l, x, y);
        indics.push(...aa.indices.map((value) => { value += vec.length / 3; return value; }));
        vec.push(...aa.vertices);

        let bb = this.ellipse(b, l, x, y);
        indics.push(...bb.indices.reverse().map((value) => { value += vec.length / 3; return value; }));
        vec.push(...bb.vertices);

        //2个侧面
        let no = vec.length / 3;

        for (let i: number = 0; i < a.length - 3; i += 3) {
            //绕y轴旋转90度处理 x = 0, z = x;
            //绕x轴旋转90度处理 y = -z, z = y;
            // let a1 = [a[i + 2], -a[i], a[i + 1]];
            // let a2 = [a[i + 5], -a[i + 3], a[i + 4]];

            // let b1 = [b[i + 2], -b[i], b[i + 1]];
            // let b2 = [b[i + 5], -b[i + 3], b[i + 4]];

            let a1 = [a[i], a[i + 1], a[i + 2]];
            let a2 = [a[i + 3], a[i + 4], a[i + 5]];

            let b1 = [b[i], b[i + 1], b[i + 2]];
            let b2 = [b[i + 3], b[i + 4], b[i + 5]];

            vec.push(...a1, ...a2, ...b1, ...b2);
            indics.push(no, no + 1, no + 2);
            indics.push(no + 2, no + 1, no + 3);
            no += 4;


            let a3 = [a[i] + l, a[i + 1], a[i + 2]];
            let a4 = [a[i + 3] + l, a[i + 4], a[i + 5]];

            let b3 = [b[i] + l, b[i + 1], b[i + 2]];
            let b4 = [b[i + 3] + l, b[i + 4], b[i + 5]];

            vec.push(...a3, ...a4, ...b3, ...b4);
            indics.push(no + 1, no, no + 2);
            indics.push(no + 2, no + 3, no + 1);
            no += 4;
        }

        return {
            vertices: vec,
            indices: indics,
            meshface: []
        }
    }


    /** 弧面
     *  l == 弧宽
    */
    private ellipse(ps: Array<any>, l: number = 600, sw = 50, sl = 50): GeometryReturnMeta<Array<any>> {
        let vec = [];
        let indics = [];
        let no = 0;



        for (let i: number = 0; i < ps.length; i += 3) {
            //先平移

            let x = ps[i];
            let y = ps[i + 1];
            let z = ps[i + 2];

            x -= sw;

            //绕x 180 z=y y=-z
            y = -y;


            // //绕y 90 x = z, z = -x;
            let t = z;
            z = -x;
            x = t;

            y += sl;


            ps[i] = x;
            ps[i + 1] = y;
            ps[i + 2] = z;
        }


        for (let i: number = 0; i <= ps.length - 6; i += 3) {
            //绕y轴旋转90度处理 x = , z = x;
            //绕x轴旋转180度处理 y = -z, z = y;

            vec.push(ps[i], ps[i + 1], ps[i + 2]);
            vec.push(ps[i] + l, ps[i + 1], ps[i + 2]);

            vec.push(ps[3], ps[i + 4], ps[i + 5]);
            vec.push(ps[3] + l, ps[i + 4], ps[i + 5]);

            // vec.push(-ps[i+2] , ps[i + 1], ps[i]);  //0
            // vec.push(-(ps[i+2] - l), ps[i + 1], ps[i]);  //1

            // vec.push(-ps[i + 5], ps[i + 4], ps[i+3]);  //2
            // vec.push(-(ps[i + 5] - l) , ps[i + 4], ps[i+3]);   //3


            //镜像
            // let 






            indics.push(no + 1, no + 3, no);
            indics.push(no, no + 3, no + 2);
            no += 4;
        }

        return {
            vertices: vec,
            indices: indics,
            meshface: []
        }
    }


    /** 易拆*/
    private _gap(data: AIBasicParams) {
        let type = data.p_yctype;
        if (!type) return;

        let angle = type == 1 ? 180 - + data["xcjd"] : +data["xcjd"]
        this._gap_board(data, +data.L * 0.5, -1 * angle);
        this._gap_board(data, +data.L * 0.5 + +data.bkT, -1 * angle);
    }


    /** 侧板 */
    private _gap_board(data: AIBasicParams, offsetX: number, angle: number) {
        let l = +data.W, sl = 50, sw = 50, w = +data.BKH, t = +data.bkT;

        //切变补齐
        let a = -1 * angle - 90;
        let aa = a / 180 * Math.PI;
        let tt = Math.tan(aa);
        let ss = t * tt;

        let ww = w + ss;

        let back = [
            sw, 0, 0, w, 0, 0, w, l, 0, 0, l, 0, 0, sl, 0
        ];

        let front = [
            sw + ss, 0, t, w + ss, 0, t, w + ss, l, t, ss, l, t, ss, sl, t
        ];





        let holes = AModelFmulaUtils.getHolesbyExpress(data["p_yckw"], l);
        // let filterHole = AluGeoUtil.filterHole(l - sl - (+data.BKDia * 0.5), holes);
        // holes = AModelFmulaUtils.getHolesbyExpress(data.p_yckw, l, 2, null, null, Math.abs(filterHole.length - holes.length));

        let h = new HoleMeta(data.BKDia * 0.5, w - (+data.BKKJMDis), AluGeoUtil.reverseHole(l, holes));

        // let h = new HoleMeta(data.BKDia * 0.5, w - bj, hole);
        let c = new CreateMeta(t, front, back, h);
        let r = AluGeoUtil.createBoardWithHole(c);

        let q = new Quaternion();
        let ar = angle / 180 * Math.PI;
        q.setFromAxisAngle(new Vector3(0, 1, 0), ar);

        for (let i: number = 0; i < r.vertices.length; i += 3) {
            VectorUtils.assistVector3.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]);
            VectorUtils.assistVector3.applyQuaternion(q);

            r.vertices[i] = VectorUtils.assistVector3.x + offsetX;
            r.vertices[i + 1] = VectorUtils.assistVector3.y;
            r.vertices[i + 2] = VectorUtils.assistVector3.z;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }


    /** 横肋*/
    private _rib(data: AIBasicParams) {

        let h = AModelFmulaUtils.getHolesbyExpress(data.p_hldw, +data.L);

        for (let offL of h) {
            if (offL > 0) {
                this._rib_board(data, offL);
            }
        }
    }


    private _rib_board(data: AIBasicParams, offsetX: number) {
        let l = +data.W - +data.bkT - this._b_t, sl = 50 - +data.bkT, sw = 50, w = +data.HLH, t = +data.HLW;

        let back = [
            sw, 0, -t, w, 0, -t, w, l, -t, 0, l, -t, 0, sl, -t
        ];

        let front = [
            sw, 0, 0, w, 0, 0, w, l, 0, 0, l, 0, 0, sl, 0
        ];

        let c = new CreateMeta(t, front, back, null);
        let r = AluGeoUtil.createBoardWithHole(c);

        let q = new Quaternion();
        q.setFromAxisAngle(new Vector3(0, 1, 0), Math.PI * -0.5);
        for (let i: number = 0; i < r.vertices.length; i += 3) {
            VectorUtils.assistVector3.set(r.vertices[i], r.vertices[i + 1], r.vertices[i + 2]);
            VectorUtils.assistVector3.applyQuaternion(q);

            r.vertices[i] = VectorUtils.assistVector3.x + offsetX;
            r.vertices[i + 1] = VectorUtils.assistVector3.y + this._b_t;
            r.vertices[i + 2] = VectorUtils.assistVector3.z + +data.GMT;
        }

        let len = this._vertices.length / 3;
        this._indices.push(...r.indices.map((v) => { return v + len }));
        this._vertices.push(...r.vertices);
    }

}